using System.Data;
using System.Security.Cryptography;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Identity.Interface;
using Identity.Models;

using Identity.Contexts;

namespace Identity.Service;
/// <summary>
/// 
/// </summary>
/// <param name="factory"></param>
public class UserService(IDbContextFactory<SysContext> factory, IConfiguration configuration) : IUser
{
    private IDbContextFactory<SysContext> DbFactory { get; } = factory;
    private IConfiguration Configuration { get; } = configuration;

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public List<User> GetAll()
    {
        using var context = DbFactory.CreateDbContext();
        return [.. context.Users.Include(u => u.UserRoles) .ThenInclude(ur => ur.Role)];  
   
    }


 
    /// <summary>
    /// 
    /// </summary>
    /// <param name="userName"></param>
    /// <returns></returns>
    public List<string> GetRoles(string userName)
    {
        using var context = DbFactory.CreateDbContext();
        return (from r in context.Roles
                join ur in context.UserRoles on r.Id equals ur.RoleId
                join u in context.Users on ur.UserId equals u.Id
                where u.UserName == userName
                select r.Name).AsNoTracking().ToList();
    }



    /// <summary>
    /// 
    /// </summary>
    /// <param name="roleId"></param>
    // /// <returns></returns>
    public List<string> GetUsersByRoleId(string? roleId)
    {
        using var context = DbFactory.CreateDbContext();
        return context.UserRoles.Where(s => s.RoleId == roleId).Select(s => s.UserId!).AsNoTracking().ToList();
    }



    /// <summary>
    /// 
    /// </summary>
    /// <param name="roleId"></param>
    /// <param name="userIds"></param>
    /// <returns></returns>
    public bool SaveUsersByRoleId(string? roleId, IEnumerable<string> userIds)
    {
        using var dbcontext = DbFactory.CreateDbContext();
        dbcontext.Database.ExecuteSqlRaw("delete from UserRoles where RoleID = {0}", roleId!);
        dbcontext.AddRange(userIds.Select(g => new UserRole { UserId = g, RoleId = roleId }));
        dbcontext.SaveChanges();
        return true;
    }



    /// <summary>
    /// 
    /// </summary>
    /// <param name="userName"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public User? GetUserByUserName(string? userName)
    {
        User? user = null;
        if (userName != null)
        {
            using var dbcontext = DbFactory.CreateDbContext();
            user = dbcontext.Set<User>().FirstOrDefault(s => s.UserName == userName);
        }
        return user;
    }
      public  bool GetMenusByUsernaem(string? userName, string menu, string appid)
    {
         using var context = factory.CreateDbContext();
       var query = 
    // 主查询：从导航表开始
    from n in context.Navigationlists
    
    // 子查询：获取用户有权限的 NavigationID
    where (
        from u in context.Users
        where u.UserName == userName
        join ur in context.UserRoles on u.Id equals ur.UserId
        join nr in context.Navigationroles on ur.RoleId equals nr.RoleId
        select nr.NavigationId
    ).Contains(n.Id) // 判断导航ID是否在权限范围内
    
    // 排序规则
    orderby n.Application, n.Order
    
    // 投影到实体
    select new Navigation
    {
        Id = n.Id,
        ParentId = n.ParentId,
        Name = n.Name,
        Order = n.Order,
        Icon = n.Icon,
        Url = n.Url,
        Category = n.Category,
        Target = n.Target,
        IsResource = n.IsResource,
        Application = n.Application,
        HasChildren = n.HasChildren
    };

    return query.Where(cm=>cm.Name==menu&&cm.Application==appid).Any();
        // 子查询：获取用户有权限的 NavigationID
 
    }

    public List<User> GetUsersByRoleName(string? RoleName)
    {
         using var context = DbFactory.CreateDbContext();
      
        var query = from u in context.Users
                    join ur in context.UserRoles on u.Id equals ur.UserId
                    join r in context.Roles on ur.RoleId equals r.Id
                    where r.Name == RoleName
                    select u;
        return query.ToList();
    }
}

